package org.lakesidecdc.outreach.client;


import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.HTMLTable.Cell;

public class ProjectList extends Composite implements ClickHandler {

	private static final int ITEMS_PER_PAGE = 10;
	
	private HTML countLabel = new HTML();
	private HTML newerButton = new HTML("<a href='javascript:;'>&lt; newer</a>", true);
	private HTML olderButton = new HTML("<a href='javascript:;'>older &rt;</a>", true);
	private int startIndex, selectedRow = -1;
	private FlexTable table = new FlexTable();
	private HorizontalPanel navBar = new HorizontalPanel();
	private Projects projects = new Projects();
	private final ProjectServiceAsync projectService = GWT.create(ProjectService.class);
	
	public ProjectList() {
		// setup the table
		table.setCellPadding(0);
		table.setCellSpacing(0);
		//table.setWidth("100%");
		
		// Hook up events
		table.addClickHandler(this);
		newerButton.addClickHandler(this);
		olderButton.addClickHandler(this);
		
		// Create the navigation bar
		HorizontalPanel innerNavBar = new HorizontalPanel();
		navBar.setStyleName("project-ListNavBar");
		innerNavBar.add(newerButton);
		innerNavBar.add(countLabel);
		innerNavBar.add(olderButton);
		
		navBar.setHorizontalAlignment(HorizontalPanel.ALIGN_RIGHT);
		navBar.add(innerNavBar);
		//navBar.setWidth("100%");
		
		initWidget(table);
		setStyleName("project-List");
		
		initTable();
		load();
	}
	
	private void load() {
		// make an rpc call to get the projects out of the datastore
		projectService.getProjects(new AsyncCallback<String[]>() {
			public void onFailure(Throwable error) {
				
			}
			public void onSuccess(String[] projectArray) {
				for(String project: projectArray) {
					Project project1 = new Project(project, null);
					projects.addProject(project1);
				}
				update();
			}
		});
	}

	@Override
	public void onClick(ClickEvent event) {
		Object sender = event.getSource();
		
		if(sender == olderButton) {
			// move forward a page
			startIndex += ITEMS_PER_PAGE;
			if(startIndex >= projects.getProjectCount()) {
				startIndex -= ITEMS_PER_PAGE;
			} else {
				styleRow(selectedRow, false);
				selectedRow = -1;
				update();
			}
		} else if (sender == newerButton) {
			// move back a page
			startIndex -= ITEMS_PER_PAGE;
			if(startIndex < 0) {
				startIndex = 0;
			} else {
				styleRow(selectedRow, false);
				selectedRow = -1;
				update();
			}
		} else if (sender == table) {
			// selected the row that was clicked (-1 to account for header row).
			Cell cell = table.getCellForEvent(event);
			if (cell != null) {
				int row = cell.getRowIndex();
				if (row > 0) {
					selectRow(row - 1);
				}
			}
		}
	}
	
	/**
	 * Initializes the table so that it contains enough rows for a full page of
	 * emails. Also creates the images that will be used as 'read' flags.
	 */
	private void initTable() {
		// Create header row
		table.setText(0, 0, "Project");
		table.setText(0, 1, "Volunteer Hours");
		table.setText(0, 2, "Staff Hours");
		table.setText(0, 3, "Cost");
		table.setText(0, 4, "Efficiency");
		table.setText(0, 5, "");
		
		// Initialize the rest of the rows
		for (int i = 0; i < ITEMS_PER_PAGE; i++) {
			table.setText(i + 1, 0, "");
			table.setText(i + 1, 1, "");
			table.setText(i + 1, 2, "");
			table.getCellFormatter().setWordWrap(i + 1, 0, false);
			table.getCellFormatter().setWordWrap(i + 1, 1, false);
			table.getCellFormatter().setWordWrap(i + 1, 2, false);
			table.getFlexCellFormatter().setColSpan(i + 1, 2, 2);
		}
	}
	
	private void selectRow(int row) {
		// when a row other than the first row (the header) is clicked,
		// display its associated Project
		Project project = projects.getProject(startIndex + row);
		if(project == null) {
			return;
		}
		
		styleRow(selectedRow, false);
		styleRow(row, true);
		
		selectedRow = row;
		LakesideOutreachManager.get().displayProject(project);
	}
	
	private void styleRow(int row, boolean selected) {
		if(row != -1) {
			if(selected) {
				table.getRowFormatter().addStyleName(row + 1, "project-SelectedRow");
			} else {
				table.getRowFormatter().removeStyleName(row + 1, "project-SelectedRow");
			}
		}
	}
	
	public void update() {
		// Update the older/newer buttons and label.
		int count = projects.getProjectCount();
		int max = startIndex + ITEMS_PER_PAGE;
		if (max > count) {
			max = count;
		}
		
		newerButton.setVisible(startIndex != 0);
		olderButton.setVisible(startIndex + ITEMS_PER_PAGE < count);
		countLabel.setText("" + (startIndex + 1) + " - " + max + " of " + count);
		
		// Show the selected projects
		int i = 0;
		for (; i < ITEMS_PER_PAGE; ++i) {
			// don't read past the end
			if(startIndex + i >= projects.getProjectCount()) {
				break;
			}
			
			Project project = projects.getProject(startIndex + i);
			
			// add a new row to the table and enter the project info
			table.setText(i + 1, 0, project.getName());
//			table.setText(i + 1, 1, Float.toString(project.getVolunteerHours()));
//			table.setText(i + 1, 2, Float.toString(project.getStaffHours()));
//			table.setText(i + 1, 3, NumberFormat.getCurrencyFormat().format(project.getCost()));
//			table.setText(i + 1, 4, Float.toString(project.getEfficiency()));
		}
		
		// clear any empty rows
		for (; i < ITEMS_PER_PAGE; ++i) {
			table.setText(i + 1, 0, "");
			table.setText(i + 1, 1, "");
			table.setText(i + 1, 2, "");
			table.setText(i + 1, 3, "");
			table.setText(i + 1, 4, "");
		}
		
		// select first row if none is selected
		if (selectedRow == -1) {
			selectRow(0);
		}
	}
	
	public boolean addProject(Project project) {
		return projects.addProject(project);
	}
}
